package rbac.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import rbac.dao.PermissionDao;
import rbac.dao.RoleDao;
import rbac.entity.RbacPermission;
import rbac.entity.RbacRole;
import rbac.enums.EntityDoNotExistExceptionMessage;
import rbac.exception.EntityDoNotExistException;
import rbac.service.RoleService;


/**
 * RBAC 角色管理 service 实现类.
 * 
 * @author Huadi
 * @author Zoufengyang
 */
@Service("roleService")
public class RoleServiceImpl implements RoleService {

	@Autowired
	@Qualifier("roleDao")
	private RoleDao roleDao;

	@Autowired
	@Qualifier("permissionDao")
	private PermissionDao permissionDao;

	@Override
	public void delete(RbacRole role) {
		roleDao.delete(role);
	}

	@Override
	public void delete(Integer roleId) {
		roleDao.delete(roleId);
	}

	@Override
	public List<RbacRole> getAllRoles() {
		return roleDao.getAllRoles();
	}

	@Override
	public RbacRole getRole(Integer id) {
		return roleDao.getRole(id);
	}

	@Override
	public void save(RbacRole role) {
		roleDao.save(role);
	}

	@Override
	public void update(RbacRole role) throws EntityDoNotExistException {
		if (null != roleDao.getRole(role.getId())) {
			roleDao.update(role);
		} else {
			throw new EntityDoNotExistException(
					EntityDoNotExistExceptionMessage.UserGroupDoNotExist);
		}
	}

	@Override
	public void grantPermissionToRole(RbacPermission permission, RbacRole role)
			throws EntityDoNotExistException {
		if (!role.getPermissions().contains(permission)) {
			role.getPermissions().add(permission);
			this.update(role);
		}
	}

	@Override
	public void grantPermissionToRole(Integer permissionId, Integer roleId)
			throws EntityDoNotExistException {
		RbacPermission permission = permissionDao.getPermission(permissionId);
		if (null == permission) {
			throw new EntityDoNotExistException(
					EntityDoNotExistExceptionMessage.PermissionDoNotExist);
		}
		RbacRole role = roleDao.getRole(roleId);
		if (null == role) {
			throw new EntityDoNotExistException(
					EntityDoNotExistExceptionMessage.RoleDoNotExist);
		}

		this.grantPermissionToRole(permission, role);
	}

	@Override
	public void revokePermissionFromRole(RbacPermission permission,
			RbacRole role) throws EntityDoNotExistException {
		if (role.getPermissions().remove(permission)) {
			this.update(role);
		}
	}

	@Override
	public void revokePermissionFromRole(Integer permissionId, Integer roleId)
			throws EntityDoNotExistException {
		RbacPermission permission = permissionDao.getPermission(permissionId);
		if (null == permission) {
			throw new EntityDoNotExistException(
					EntityDoNotExistExceptionMessage.PermissionDoNotExist);
		}
		RbacRole role = roleDao.getRole(roleId);
		if (null == role) {
			throw new EntityDoNotExistException(
					EntityDoNotExistExceptionMessage.RoleDoNotExist);
		}

		this.revokePermissionFromRole(permission, role);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
	public void grantPermissionToRole(Integer roleId,
			List<Integer> selectedPermissionIds)
			throws EntityDoNotExistException {
		RbacRole role = roleDao.getRole(roleId);
		Set<RbacPermission> permissionSet = new HashSet<RbacPermission>();
		for (Integer permissionId : selectedPermissionIds) {
			RbacPermission p = permissionDao.getPermission(permissionId);
			if (null != p) {
				permissionSet.add(p);
			}
		}
		role.setPermissions(permissionSet);
		this.update(role);
	}

}
